package com.essential.bases;

/*
如果我们有一组类型相同的变量，例如，5位同学的成绩，其实没有必要定义5个int变量。可以使用数组来表示“一组”int类型。代码如下：
 */
public class ArrayType {

    /*
    Java的数组有几个特点：
    定义一个数组类型的变量，使用数组类型“类型[]”，例如，int[]。
    和单个基本类型变量不同，数组变量初始化必须使用new int[5]
    表示创建一个可容纳5个int元素的数组。
    数组所有元素初始化为默认值，整型都是0，浮点型是0.0，布尔型是false；
    数组一旦创建后，大小就不可改变。
    要访问数组中的某一个元素，需要使用索引。数组索引从0开始，例如，5个元素的数组，索引范围是0~4。
    可以修改数组中的某一个元素，使用赋值语句，例如，ns[1] = 79;。
    可以用数组变量.length获取数组大小：
    数组是引用类型，在使用索引访问数组元素时，如果索引超出范围，运行时将报错：
    也可以在定义数组时直接指定初始化的元素，这样就不必写出数组大小，而是由编译器自动推算数组大小
    注意数组是引用类型，并且数组大小不可变。
    可缩写为int[] ns = { 68, 79, 91, 85, 62 };

    ##小结
        数组是同一数据类型的集合，数组一旦创建后，大小就不可变；
        可以通过索引访问数组元素，但索引超出范围将报错；
        数组元素可以是值类型（如int）或引用类型（如String），但数组本身是引用类型；
     */
    public static void main(String[] args) {

        // 5位同学的成绩:
        /*
        *创建数组的一种方式
        *length的用途
        *索引不超出范围
         */
        int[] ns = new int[5];
        System.out.println("ns数组大小为"+ns.length); // 通过length获取数组大小
        ns[0] = 68;
        ns[1] = 79;
        ns[2] = 91;
        ns[3] = 85;
        ns[4] = 62;
        //System.out.println(ns[5]); //索引不能超出范围，不然会引发错误

        /*
        *创建数组的另一种方式
        * 自动推算数组大小
        *
         */

        int[] ns1 = new int[] { 68, 79, 91, 85, 62 };// 在定义数组时直接指定初始化的元素，这样就不必写出数组大小，而是由编译器自动推算数组大小
        //可缩写为==>int[] ns = { 68, 79, 91, 85, 62 };
        System.out.println(ns.length); // 编译器自动推算数组大小为5

    }
    /*难点
             int[] ns;
                ns = new int[] { 68, 79, 91, 85, 62 };
                System.out.println(ns.length); // 5
                ns = new int[] { 1, 2, 3 };
                System.out.println(ns.length); // 3
        对于数组ns来说，执行ns = new int[] { 68, 79, 91, 85, 62 };时，它指向一个5个元素的数组：

             ns
              │
              ▼
        ┌───┬───┬───┬───┬───┬───┬───┐
        │   │68 │79 │91 │85 │62 │   │
        └───┴───┴───┴───┴───┴───┴───┘
        执行ns = new int[] { 1, 2, 3 };时，它指向一个新的3个元素的数组：

             ns ──────────────────────┐
                                      │
                                      ▼
        ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
        │   │68 │79 │91 │85 │62 │   │ 1 │ 2 │ 3 │   │
        └───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
        但是，原有的5个元素的数组并没有改变，只是无法通过变量ns引用到它们而已。


        字符串数组
        如果数组元素不是基本类型，而是一个引用类型，那么，修改数组元素会有哪些不同？

        字符串是引用类型，因此我们先定义一个字符串数组：

        String[] names = {
            "ABC", "XYZ", "zoo"
        };
        对于String[]类型的数组变量names，它实际上包含3个元素，但每个元素都指向某个字符串对象：

                  ┌─────────────────────────┐
            names │   ┌─────────────────────┼───────────┐
              │   │   │                     │           │
              ▼   │   │                     ▼           ▼
        ┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┐
        │   │░░░│░░░│░░░│   │ "ABC" │   │ "XYZ" │   │ "zoo" │   │
        └───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┘
              │                 ▲
              └─────────────────┘
        对names[1]进行赋值，例如names[1] = "cat";，效果如下：

                  ┌─────────────────────────────────────────────────┐
            names │   ┌─────────────────────────────────┐           │
              │   │   │                                 │           │
              ▼   │   │                                 ▼           ▼
        ┌───┬───┬─┴─┬─┴─┬───┬───────┬───┬───────┬───┬───────┬───┬───────┬───┐
        │   │░░░│░░░│░░░│   │ "ABC" │   │ "XYZ" │   │ "zoo" │   │ "cat" │   │
        └───┴─┬─┴───┴───┴───┴───────┴───┴───────┴───┴───────┴───┴───────┴───┘
              │                 ▲
              └─────────────────┘
        这里注意到原来names[1]指向的字符串"XYZ"并没有改变，仅仅是将names[1]的引用从指向"XYZ"改成了指向"cat"，其结果是字符串"XYZ"再也无法通过names[1]访问到了。


     */
}
